package com.zxkj.ssm.weixin.shop.config.shiro;
import com.zxkj.ssm.weixin.shop.shiro.CluterShiroSessionDao;
import com.zxkj.ssm.weixin.shop.shiro.UserRealm;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import java.io.IOException;

/**
 * @Author 程序媛
 * @Date @2017年7月28日
 * @Description:权限框架SHiro组件配置
 */

@Configuration
public class ShiroConfiguration implements EnvironmentAware  {//实现EnvironmentAware  注入env 环境 不然为null
	private Environment env;
	@Override
	public void setEnvironment(Environment environment) {
		this.env=environment;
	}


	@Bean
	public UserRealm userRealm(){
		UserRealm realm=new UserRealm();
		return  realm;
	}
	@Bean
	public CluterShiroSessionDao cluterShiroSessionDao(){
		CluterShiroSessionDao cluterShiroSessionDao=new CluterShiroSessionDao();
		return  cluterShiroSessionDao;
	}


	/**
	 * 会话管理
	 * @return
	 */
	@Bean
	public DefaultWebSessionManager defaultWebSessionManager(CluterShiroSessionDao cluterShiroSessionDao){
		DefaultWebSessionManager sessionManager=new DefaultWebSessionManager();
		sessionManager.setGlobalSessionTimeout(Long.parseLong(//
				env.getProperty("shiro.globalSessionTimeout")));
		sessionManager.setDeleteInvalidSessions(Boolean.parseBoolean(//
				env.getProperty("shiro.deleteInvalidSessions")));
		sessionManager.setSessionValidationSchedulerEnabled(//
				Boolean.parseBoolean(env.getProperty("shiro.sessionValidationSchedulerEnabled")));
		sessionManager.setSessionDAO(cluterShiroSessionDao);
		return sessionManager;

	}

	/**
	 *  安全认证管理器
	 * @return
	 */
	@Bean
	public DefaultWebSecurityManager defaultWebSecurityManager(DefaultWebSessionManager defaultWebSessionManager, UserRealm authenticationRealm ){
		DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
		defaultWebSecurityManager.setRealm(authenticationRealm);
		defaultWebSecurityManager.setSessionManager(defaultWebSessionManager);
		return 	defaultWebSecurityManager;
	}


	/**
	 * Shiro生命周期处理器
	 * 用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调
	 * @return
	 */
	@Bean(name="lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
		return new LifecycleBeanPostProcessor();
	}

	/**
	 * 决定对哪些类的方法进行AOP代理。
	 */
	@Bean
	@ConditionalOnMissingBean
	@DependsOn("lifecycleBeanPostProcessor")
	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
		creator.setProxyTargetClass(true);
		return creator;
	}

	/**
	 * AuthorizationAttributeSourceAdvisor，shiro里实现的Advisor类，
	 * 内部使用AopAllianceAnnotationsAuthorizingMethodInterceptor来拦截用以下注解的方法(如@RequiresRoles，@RequiresPermissions)，。
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager){
		AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(defaultWebSecurityManager);
		return advisor;
	}

	/**
	 * Shiro 主过滤器
	 * @return
	 * @throws Exception
	 */
	@Bean(name="shiroFilter")
	public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) throws Exception{
		ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
		shiroFilterFactoryBean.setLoginUrl(env.getProperty("shiro.login.url"));
		shiroFilterFactoryBean.setSuccessUrl(env.getProperty("shiro.success.url"));
		shiroFilterFactoryBean.setUnauthorizedUrl(env.getProperty("shiro.unauthorized.url"));
		try {
			shiroFilterFactoryBean.setFilterChainDefinitions(
					FileUtils.readFileToString(new DefaultResourceLoader(
					).getResource(env.getProperty("shiro.filter.link")).getFile(),"UTF-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return  shiroFilterFactoryBean;
	}




}
